package mx.uach.compiladores;

import mx.uach.compiladores.Token;
import com.sun.corba.se.impl.util.PackagePrefixChecker;
import java.util.StringTokenizer;

/**
 *
 * @author Alejandro Amaro Montes
 * @version 1.0
 * @since 6/03/2015
 */
public class AnalizadorSintacticoAvanzado {

    private static final int FIN_SENT = ';';
    private static final int SUMA = '+';
    private static final int RESTA = '-';
    private static final int MULTIPLICACION = '*';
    private static final int DIVISION = '/';
    private static final int PAR_DER = ')';
    private static final int PAR_IZQ = '(';
    private static final int NUMERO = 600;
    private static final int ID = 700;

    private Integer linea = 1;
    private StringTokenizer tokenizer;

    private StringTokenizer getTokenizer(String codigoFuente) {
        if (this.tokenizer == null) {
            String alfabeto = String.format("%s%s%s%s%s%s%s",
                    (char) FIN_SENT,
                    (char) SUMA,
                    (char) RESTA,
                    (char) MULTIPLICACION,
                    (char) DIVISION,
                    (char) PAR_DER,
                    (char) PAR_IZQ
            );
            this.tokenizer = new StringTokenizer(codigoFuente.trim(), alfabeto, true);
        }
        return this.tokenizer;
    }

    private Token lex(String codigoFuente) {
        Token token = null;

        String currentToken
                = this.getTokenizer(codigoFuente).nextToken();
        if (esNumero(currentToken)) {
            token = new Token(this.linea, NUMERO, currentToken);
        } else {
            int tokenSimple = currentToken.charAt(0);
            switch (tokenSimple) {
                case FIN_SENT:
                    token = new Token(this.linea, FIN_SENT,
                            String.format("%S", (char) tokenSimple));
                    linea++;
                    break;
                case SUMA:
                    token = new Token(this.linea, SUMA,
                            String.format("%S", (char) tokenSimple));
                    linea++;
                    break;
                case RESTA:
                    token = new Token(this.linea, RESTA,
                            String.format("%S", (char) tokenSimple));
                    linea++;
                    break;
                case MULTIPLICACION:
                    token = new Token(this.linea, MULTIPLICACION,
                            String.format("%S", (char) tokenSimple));
                    linea++;
                    break;
                case DIVISION:
                    token = new Token(this.linea, DIVISION,
                            String.format("%S", (char) tokenSimple));
                    linea++;
                    break;
                case PAR_DER:
                    token = new Token(this.linea, PAR_DER,
                            String.format("%S", (char) tokenSimple));
                    linea++;
                    break;
                case PAR_IZQ:
                    token = new Token(this.linea, PAR_IZQ,
                            String.format("%S", (char) tokenSimple));
                    linea++;
                    break;

                default:
                    throw new AssertionError();
            }
        }
        return token;
    }

    public static Boolean esNumero(String textoRevisar) {
        Boolean esNumero = true;
        for (int i = 0; i < textoRevisar.length(); i++) {
            esNumero = esNumero && Character.isDigit(textoRevisar.charAt(i));

        }
        return esNumero;
    }

    public static void main(String... args) {
        AnalizadorSintacticoAvanzado analizador
                = new AnalizadorSintacticoAvanzado();
        while (analizador.getTokenizer("5+3").hasMoreTokens()) {
            Token t = analizador.lex("");
            System.out.println(t);
        }
    }
}
